#include "stdafx.h"
#include <boost/test/auto_unit_test.hpp>
#include "detail/bmock_raw_mem.hpp"
#include "bmock_util.hpp"
#include "detail/bmock_message.hpp"
#include "detail/bmock_test_control_tools.hpp"

namespace bmock {
	static const unsigned char data1[]   = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
		,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
	static const size_t        L1        = sizeof(data1);
	static const std::string         expected1 = "000102030405060708090A0B0C0D0E0F";

	static const size_t L2        = 5;
	static const int    data2[L2] = {1,2,3,4,16};
	static const std::string  expected2 = "0100000002000000030000000400000010000000";

	BOOST_AUTO_TEST_CASE(test_get_value) {
		raw_mem  m(data1,L1);
		std::string   result;

		BOOST_CHECK_NO_THROW(result = m.get_value());
		BOOST_CHECK_EQUAL(data1,m.get_ptr());
		BOOST_CHECK_EQUAL(expected1,result);
	}

	BOOST_AUTO_TEST_CASE(test_get_value_null) {
		raw_mem  m(0,0);
		std::string   result;

		BOOST_CHECK_NO_THROW(result = m.get_value());
		BOOST_CHECK_EQUAL((const void *)NULL,(const void *)m.get_ptr());
		BOOST_CHECK_EQUAL(size_t(0),m.get_length());
		BOOST_CHECK_EQUAL(NULL_STR,result);
	}

	BOOST_AUTO_TEST_CASE(test_get_value_zero_length) {
		raw_mem  m(data1,0);
		std::string   result;

		BOOST_CHECK_NO_THROW(result = m.get_value());
		BOOST_CHECK_EQUAL((const void *)data1,(const void *)m.get_ptr());
		BOOST_CHECK_EQUAL(size_t(0),m.get_length());
		BOOST_CHECK_EQUAL("",result);
	}

	BOOST_AUTO_TEST_CASE(test_get_value_int_input) {
		raw_mem  m(data2,L2);
		std::string   result;

		BOOST_CHECK_NO_THROW(result = m.get_value());
		BOOST_CHECK_EQUAL(expected2,result);
	}

	BOOST_AUTO_TEST_CASE(test_get_T_value_int) {
		int      data3 = 9756;
		raw_mem  m(&data3,1);
		std::string   result;
		std::string   expected3 = boost::lexical_cast<std::string>(data3);

		BOOST_CHECK_NO_THROW(result = m.get_T_value<int>());
		BOOST_CHECK_EQUAL(expected3,result);
	}

	BOOST_AUTO_TEST_CASE(test_get_T_value_zero_length) {
		int      data3 = 9756;
		raw_mem  m(&data3,0);
		std::string   result;

		BOOST_CHECK_NO_THROW(result = m.get_T_value<int>());
		BOOST_CHECK_EQUAL(NULL_STR,result);
	}

	BOOST_AUTO_TEST_CASE(test_get_T_value_str) {
		char     data4[] = "qwertyuiop";
		raw_mem  m(&data4,sizeof(data4));
		std::string   result;
		std::string   expected4 = std::string(data4);

		BOOST_CHECK_NO_THROW(result = m.get_str_value());
		BOOST_CHECK_EQUAL(expected4,result);
	}

	BOOST_AUTO_TEST_CASE(test_set_value_OK) {
		unsigned char           buf[L1];
		const raw_mem           m(buf,sizeof(buf));
		const char name[] =     "raw_mem(buf,sizeof(buf))";
		const control_tools_ptr t(new test_control_tools());
		raw_mem_checker         chk(t);

		BOOST_CHECK_NO_THROW(m.set_value(name,chk,expected1));
		BOOST_CHECK_EQUAL(mismatch_at(buf,buf+L1,data1),L1);
	}

	BOOST_AUTO_TEST_CASE(test_in_out_rm_pair_empty) {
		const control_tools_ptr t(new test_control_tools());
		raw_mem_checker         chk(t);
		in_out_rm_pair          rmp(NULL,"null rmp",chk);

		BOOST_CHECK(rmp.first.is_empty());
		BOOST_CHECK(rmp.second.is_empty());
	}

	BOOST_AUTO_TEST_CASE(test_get_T_ptr) {
		char     data4[] = "qwertyuiop";
		raw_mem  m(&data4,sizeof(data4));
		char*   result;
		std::string   expected4 = std::string(data4);

		BOOST_CHECK_NO_THROW(result = m.get_T_ptr<char>());
		BOOST_CHECK_EQUAL(expected4,result);
	}
}